import 'dart:async';

import 'package:juju/fake/fake_data.dart';

class MessageFlutter {
  void init() {}

  void addContactNotifyListener(Null Function(dynamic event) param0) {}

  login({required String username, required String password}) {}

  getMyInfo() {
    return UserInfo.fromJson(myInfo);
    // return null;
  }

  userRegister({required String username, required String password}) {}

  getConversations() {
    return List.generate(
        friendConvesation.length,
        (int index) => ConversationInfo.fromJson({
              'conversationType': 'single',
              'title': 'hi',
              'target': friendConvesation.elementAt(index),
              'latestMessage': {
                'isSend': true,
                'text': 'hello',
                'from': friendConvesation.elementAt(index),
                'target': myInfo
              }
            }),
        growable: true);
  }

  updateMyInfo(
      {int? birthday,
      String? nickname,
      String? signature,
      String? region,
      String? address,
      Gender? gender,
      Map? extras}) {}

  Future<List<UserInfo>> getFriends() async {
    List<UserInfo> users =
        friendConvesation.map((userMap) => UserInfo.fromJson(userMap)).toList();
    return users;
  }

  Future<ConversationInfo> getConversation({required dynamic target}) async {
    return getConversationAsync(target: target);
  }

  ConversationInfo getConversationAsync({required dynamic target}) {
    Map param = target.toJson();
    ConversationInfo conversationInfo = ConversationInfo.fromJson({
      'title': 'hello',
      'target': param,
      'latestMessage': {
        'isSend': true,
        'text': 'hello',
        'from': target.toJson(),
        'target': myInfo
      },
      'conversationType': param['type']
    });
    return conversationInfo;
  }

  createConversation({required Single target}) {}

  void logout() {}

  updateMyAvatar({required String imgPath}) {}

  downloadThumbUserAvatar({required String username}) {}

  sendInvitationRequest({required String username, required String reason}) {}

  enterConversation({Single? target}) {}

  acceptInvitation({required String username}) {}
}

class ConversationInfo {
  ConversationType conversationType;

  String title;

  late dynamic target;

  TextMessage? latestMessage;

  ConversationInfo.fromJson(Map<dynamic, dynamic> json)
      : conversationType = getEnumFromString(
            ConversationType.values, json['conversationType']),
        title = json['title'] {
    switch (conversationType) {
      case ConversationType.single:
        target = UserInfo.fromJson(json['target']);
        break;
      case ConversationType.group:
        // TODO: Handle this case.
        break;
      case ConversationType.chatRoom:
        // TODO: Handle this case.
        break;
    }
    if (json.containsKey("latestMessage")) {
      latestMessage = TextMessage.fromJson(json['latestMessage']);
    }
  }

  Future<List> getHistoryMessages(
      {required int? from, required int? limit, bool isDescend = false}) async {
    List msgs = List.from(textMessages);
    return msgs;
  }

  sendTextMessage({required String text}) {}
}

class Single {
  final ConversationType type = ConversationType.single;
  String? username;
  String? appKey;

  Map toJson() {
    return {
      "type": getStringFromEnum(ConversationType.single),
      "username": username,
      "appKey": appKey
    };
  }

  Single.fromJson(Map<dynamic, dynamic> json)
      : username = json['username'],
        appKey = json['appKey'];
}

enum ConversationType { single, group, chatRoom }

enum JMContactNotifyType {
  invite_received,
  invite_accepted,
  invite_declined,
  contact_deleted
}

enum Gender { male, female, unknown }

enum TargetType { user, group }

class ContactNotifyEvent {
  var fromUserName;

  var reason;

  var type;
}

class UserInfo {
  TargetType type = TargetType.user;

  String username;

  String avatarThumbPath;

  String nickname; // 用户名

  UserInfo.fromJson(Map<dynamic, dynamic> json)
      : username = json['username'],
        avatarThumbPath = json['avatarThumbPath'] ?? '',
        nickname = json['nickname'] ?? '';

  Map toJson() {
    return {
      'username': username,
    };
  }
}

class TextMessage {
  String text;
  UserInfo from;
  dynamic target;
  bool isSend;

  TextMessage.fromJson(Map<dynamic, dynamic> json)
      : text = json['text'],
        isSend = json['isSend'],
        from = UserInfo.fromJson(json['from']) {
    switch (json['target']['type']) {
      case 'user':
        target = UserInfo.fromJson(json['target']);
        break;
    }
  }

  Map toJson() {
    return {
      'isSend': isSend,
      'text': text,
      'from': from.toJson(),
      'target': target.toJson()
    };
  }
}

String? getStringFromEnum<T>(T) {
  if (T == null) {
    return null;
  }
  return T.toString().split('.').last;
}

T getEnumFromString<T>(Iterable<T> values, String str) {
  return values.firstWhere((f) => f.toString().split('.').last == str,
      orElse: null);
}
